package ldh.im.fxgui.component;

import com.jfoenix.controls.JFXButton;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import ldh.im.fxbase.dao.ImSessionDao;
import ldh.im.fxbase.data.dto.SearchResult;
import ldh.im.fxbase.data.pojo.ImGroup;
import ldh.im.fxbase.data.pojo.ImSession;
import ldh.im.fxbase.data.pojo.ImUser;
import ldh.im.fxbase.util.*;
import ldh.im.fxgui.component.cell.SearchResultView;
import ldh.im.fxgui.controller.MessageSessionController;
import ldh.im.fxgui.controller.sub.SearchController;
import ldh.im.fxgui.pojo.WrapSearchResult;
import ldh.im.fxgui.util.UiUtil;
import org.fxmisc.flowless.Cell;
import org.fxmisc.flowless.VirtualFlow;
import org.fxmisc.flowless.VirtualizedScrollPane;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 聊天-》会话-》搜索
 */
public class SearchResultPane extends StackPane {

    private String search;
    private boolean userMore = false;
    private boolean groupMore = false;

    private ObservableList<WrapSearchResult> searchResultDatas = FXCollections.observableArrayList();
    private VirtualFlow<WrapSearchResult, ?> searchResultVirtualFlow;
    private VirtualizedScrollPane virtualizedScrollPane;

    private ImStage searchMessageStage = null;
    private MessageSessionController messageSessionController;

    public SearchResultPane(MessageSessionController messageSessionController) {
        this.messageSessionController = messageSessionController;
        this.getStyleClass().add("search-result-pane");
        initUi();
    }

    public void setData(String search, List<SearchResult> userSearchResults, List<SearchResult> groupSearchResults, List<SearchResult> messageSearchResults) {
        this.search = search;
        searchResultDatas.clear();

        if (userSearchResults.size() > 0) {
            searchResultDatas.add(new WrapSearchResult(search, "联系人"));
            List<WrapSearchResult> wrapSearchResults = userSearchResults.stream().map(r-> new WrapSearchResult(search, r)).collect(Collectors.toList());

            if (wrapSearchResults.size() > ParamUtil.SEARCH_USER_SIZE) {
                List<WrapSearchResult> wrapSearchResults1 = wrapSearchResults.subList(0, ParamUtil.SEARCH_USER_SIZE);
                List<WrapSearchResult> wrapSearchResults2 = wrapSearchResults.subList(ParamUtil.SEARCH_USER_SIZE, wrapSearchResults.size());
                searchResultDatas.addAll(wrapSearchResults1);

                int size = searchResultDatas.size();
                JFXButton jfxButton = new JFXButton("更多");

                jfxButton.setOnAction(e->{
                    if (!userMore) {
                        searchResultDatas.addAll(size, wrapSearchResults2);
                        jfxButton.setText("收起");
                    } else {
                        searchResultDatas.removeAll(wrapSearchResults2);
                        jfxButton.setText("更多");
                    }
                    userMore = !userMore;
                });
                searchResultDatas.add(new WrapSearchResult(search, jfxButton));
            } else {
                searchResultDatas.addAll(wrapSearchResults);
                userMore = true;
            }

        }

        if (groupSearchResults.size() > 0) {
            searchResultDatas.add(new WrapSearchResult(search, "群聊"));
            List<WrapSearchResult> wrapSearchResults = groupSearchResults.stream().map(r-> new WrapSearchResult(search, r)).collect(Collectors.toList());

            if (wrapSearchResults.size() > ParamUtil.SEARCH_GROUP_SIZE) {
                List<WrapSearchResult> wrapSearchResults1 = wrapSearchResults.subList(0, ParamUtil.SEARCH_GROUP_SIZE);
                List<WrapSearchResult> wrapSearchResults2 = wrapSearchResults.subList(ParamUtil.SEARCH_GROUP_SIZE, wrapSearchResults.size());
                searchResultDatas.addAll(wrapSearchResults1);

                int size = searchResultDatas.size();
                JFXButton jfxButton = new JFXButton(String.format("显示全部(%s)", wrapSearchResults.size()));

                jfxButton.setOnAction(e->{
                    if (!groupMore) {
                        searchResultDatas.addAll(size, wrapSearchResults2);
                        jfxButton.setText("收起");
                    } else {
                        searchResultDatas.removeAll(wrapSearchResults2);
                        jfxButton.setText(String.format("显示全部(%s)", wrapSearchResults.size()));
                    }
                    groupMore = !groupMore;
                });
                searchResultDatas.add(new WrapSearchResult(search, jfxButton));
            } else {
                searchResultDatas.addAll(wrapSearchResults);
                groupMore = true;
            }

        }

        if (messageSearchResults.size() > 0) {
            searchResultDatas.add(new WrapSearchResult(search, "聊天消息"));
            List<WrapSearchResult> wrapSearchResults = messageSearchResults.stream().map(r-> new WrapSearchResult(search, r)).collect(Collectors.toList());
            if (messageSearchResults.size() > ParamUtil.SEARCH_MESSAGE_SIZE) {
                List<WrapSearchResult> wrapSearchResults1 = wrapSearchResults.subList(0, ParamUtil.SEARCH_MESSAGE_SIZE);
                searchResultDatas.addAll(wrapSearchResults1);

                JFXButton jfxButton = new JFXButton(String.format("显示全部(%s)", wrapSearchResults.size()));

                jfxButton.setOnAction(e->{
                    if (searchMessageStage == null) {
                        searchMessageStage = new ImStage(900, 600);
                        searchMessageStage.setTitle("搜聊天记录");

                        searchMessageStage.getCurrentScene().getStylesheets().add(this.getClass().getResource("/css/message-dialog.css").toExternalForm());
                        RegionUtil.FxmlBean<Node, SearchController> fxmlBean = RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/sub/SearchPane.fxml"));
                        searchMessageStage.setContent(fxmlBean.getNode());
                        fxmlBean.getController().setMessageSearchResult(search, wrapSearchResults);
                        fxmlBean.getController().setMessageSessionController(messageSessionController);
                    }
                    searchMessageStage.show();
                });
                searchResultDatas.add(new WrapSearchResult(search, jfxButton));
            } else {
                searchResultDatas.addAll(wrapSearchResults);
            }
        }

        if (searchResultDatas.size() > 0) {
            searchResultVirtualFlow.show(0);
        }
    }

    private void initUi() {
        searchResultVirtualFlow = VirtualFlow.createVertical(searchResultDatas, m->{
            SearchResultView searchResultView = new SearchResultView(m);
            searchResultView.addEventFilter(MouseEvent.MOUSE_PRESSED, e->{
                switchSession(m.getSearchResult());
            });
            return Cell.wrapNode(searchResultView);
        });

        virtualizedScrollPane = new VirtualizedScrollPane(searchResultVirtualFlow);

        this.getChildren().setAll(virtualizedScrollPane);
    }

    private void switchSession(SearchResult searchResult) {
        if (searchResult == null) return;
        Task<ImSession> sessionTask = new Task() {

            @Override
            protected Object call() throws Exception {
                String userId = UiUtil.getLoginImUser().getUserId();
                ImSessionDao sessionDao = BeanFactory.getInstance().getBean(ImSessionDao.class);
                if (searchResult.isMessage()) {
                    ImSession session = sessionDao.getSessionById(searchResult.getSessionId());
                    return session;
                }
                if (searchResult.isUser()) {
                    ImSession session = sessionDao.getByUserId(userId, userId, searchResult.getUserId());
                    if (session == null) {
                        ImUser imUser = ImCacheFactory.getInstance().getUser(searchResult.getUserId());
                        session = ImSession.build(userId, imUser);
                        sessionDao.insertSession(session);
                    }
                    return session;
                }

                if (searchResult.isGroup() || searchResult.isGroupUser()) {
                    ImSession session = sessionDao.getByGroupCodeAndUserId(searchResult.getGroupCode(), userId);
                    if (session == null) {
                        ImGroup imGroup = ImCacheFactory.getInstance().getImGroup(userId, searchResult.getGroupCode());
                        session = ImSession.build(userId, imGroup);
                        sessionDao.insertSession(session);
                    }
                    return session;
                }
                throw new RuntimeException("不支持这个类型");
            }
        };
        ThreadPoolUtil.submitTask(sessionTask);
        sessionTask.setOnSucceeded(s->{
            messageSessionController.cleanSearchText();
            messageSessionController.switchSession(sessionTask.getValue());
        });
    }

}
